Назад | Начало урока | Вперед
Содержание

Глава 1 (продолжение 1)

Вверх

Поиск лексемы и вставка строки

Эта программа построчно считывает из текстового файла, затем в строке ищет подстроку (лексему). Найдя лексему, программа вставляет перед каждой найденной лексемой новую строку. И разыскиваемая лексема и новая строка для вставки переданы программным способом (заданы программно до компиляции).

Программа 01_01


// Example_01_01 Поиск лексемы и вставка строки
#include <fstream.h>
#include <iostream.h>
#include <string.h>

//using namespace std;

char* fun1 (char *p1a,char *p3, char *p,char *p1,char *p2,
int &l_word,int &l_word1,char *word,char *word1,
ofstream &to1) {

while (p = strstr(p, word))
{

int z = 0;
z = (p - p1 );

strncpy(p2,p1,z);

p2 = p2 + z;
strcpy(p2,word1); //вставим тег <br> !!!

p2 +=l_word1; // все слова теперь слева от указателя

p1 = p;
p +=l_word;

}//end while 1

strcpy(p2,p1);

strcpy(p1a,p3);

return p2;

}

int main( int argc,char* argv[])
{

ifstream from1("text1");//открываем файл для считывания

if(!from1)
{

cout<<"Vhodnoi fail ne naiden:" ;
return (1);
}

ofstream to1("text2" ); // open for writing

if(!to1)
{

cout<<"Vyhodnoi fail ne naiden:" ;
to1.close(); // always pays to be tidy
return (1);
}

//--------------------------------------------------

const int len = 200;

char word []= "<IMG SRC=";
char word1 []= "<br>";
char wordA []= "<A HREF=";
char wordB []= "<BODY";
char wordC []= "<FRAME SRC=";
char wordD []= "<SCRIPT LANGUAGE=";
char wordE []= "<MAP NAME=";
char wordF []= "<AREA SHAPE";
char wordG []= "</MAP";
char wordH []= "<FRAMESET";
char wordI []= "<H1";
char wordJ []= "<H2";
char wordK []= "<DIV";
char wordL []= "</DIV";
char wordM []= "";

char buf[len];
char buf1[len] ;
//--------------------------------------------------
int l_word = strlen(word);
int l_word1 = strlen(word1);

char *p = buf;//сорентируем указатель на начало массива buf
char *p1 = buf;//сорентируем указатель на начало массива buf
char *p1a = buf;//сорентируем указатель на начало массива buf

char *p2 = buf1;//сорентируем указатель на начало массива buf1
char *p3 = buf1;//сорентируем указатель на начало массива buf1


while (!from1.eof())
{

from1.getline(buf,sizeof(buf));
p = buf; //сорентируем указатель на начало массива buf
p1 = buf; //сорентируем указатель на начало массива buf
p1a = buf; //сорентируем указатель на начало массива buf

p2 = buf1;//сорентируем указатель на начало массива buf
p3 = buf1;//сорентируем указатель на начало массива buf

fun1 (p1a,p3, p,p1,p2,l_word,l_word1, word, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordA, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordB, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordC, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordD, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordE, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordF, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordG, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordH, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordI, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordJ, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordK, word1,to1) ;
fun1 (p1a,p3, p,p1,p2,l_word,l_word1, wordL, word1,to1) ;

to1 << p3 << "\n"; // and write it to the file

//////////////////////////////////////////////////////////

} //end while

//--------------------------------------------------

from1.close(); // always pays to be tidy

to1.close(); // always pays to be tidy

return 0;

}


Результат:

Эта программа откомпилирована и выполнена в 6-й версии
программы Microsoft Visual C++
Результат находится в файле fileTo.txt в рабочей директории программы.

Анализ:


Ключ к работе программы находится в описании работы
ее функции fun1.

1.Сначала в главной функции main объявляем два массива

const int len = 200;
char buf[len];
char buf1[len] ;

2.Затем объявляем пять указателей на символьные массивы

char *p = buf;//сорентируем указатель на начало массива buf
char *p1 = buf;//сорентируем указатель на начало массива buf
char *p1a = buf;//сорентируем указатель на начало массива buf

char *p2 = buf1;//сорентируем указатель на начало массива buf1
char *p3 = buf1;//сорентируем указатель на начало массива buf1

И ориентируем первые три указателя на начало первого массива,
другие два указателя на начало второго массива.

3. Считываем первую строку из текстового файла в массив buf
при помощи функции getline() и снова ориентируем указатели
на начало массивов, затем вызываем функцию fun1()

while (!from1.eof())
{

from1.getline(buf,sizeof(buf));
p = buf; //сорентируем указатель на начало массива buf
p1 = buf; //сорентируем указатель на начало массива buf
p1a = buf; //сорентируем указатель на начало массива buf

p2 = buf1;//сорентируем указатель на начало массива buf
p3 = buf1;//сорентируем указатель на начало массива buf
p3a = buf1;//сорентируем указатель на начало массива buf

fun1 (p1a, p3, p, p1, p2,l_word,l_word1, word, word1, buf1, to1) ;

В качестве параметров в числе прочих передаем так же пять только
что объявленных и инициализированных указателей - p1a, p3, p, p1, p2,
массив buf1 (в данном случае передается адрес массива).

4.Рассмотрим работу функции fun1()


char* fun1 (char *p1a, char *p3, char *p,
char *p1, char *p2,int &l_word,
int &l_word1, char *word, char *word1,
char *buf1,ofstream &to1) {

while (p = strstr(p, word)) {

int z = 0;
z = (p - p1 );

strncpy(p2,p1,z);

p2 = p2 + z;
strcpy(p2,word1); //вставим тег <br> !!!

p2 +=l_word1; // все слова теперь слева от указателя

p1 = p;
p +=l_word;

}//end while 1

strcpy(p2,p1);

strcpy(p1a,p3);

return p2;

}

Анализ:

Функция имеет всего дюжину строк, но выполняет всю необходимую работу.
Все параметры являются либо указателями либо ссылками.

1. В начале в заголовке цикла while вызывается функция strstr()
которая ищет первое вхождение (первое появление) лексемы содержащейся в
массиве word в массив, на который указывает указатель p.

while (p = strstr(p, word))

У нас указатель p инициализирован на начало массива buf (помним: p = buf; //сорентируем указатель на начало массива buf)

Таким образом функция strstr ищет лексему word в массиве buf.

Возвращает функция позицию вхождения этой лексемы в массив,
то есть адрес элемента массива c которого начинается вхождение лексемы.

Теперь мы можем определить сколько символов от начала массива мы можем
скопировать из массива buf в массив buf1

int z = 0;
z = (p - p1 );

Здесь p1 у нас ориентирован на начало массива buf,
а p - на первое вхождение лексемы в массив buf.

Определяем количество символов, сохраняем их количество в z
и копируем их в массив buf1, на который указывает указатель p2

strncpy(p2,p1,z);

Таким образом мы скопировали z символов из масива buf на начало
которого указывает указатель p1 в массив buf1 на который указывает указатель p2

2. Теперь надо передвинуть указатель p2 массива buf1 вперед на z
символов, чтобы можно было вставить новую лексему, содержащуюся
в массиве word1 (в случае нашей прогаммы в word1 содержится тег)

p2 = p2 + z;
strcpy(p2,word1); //вставим тег <br> !!!

Скопировали лексему содержащуюся в word1 в нужное место массива buf1.

Далее опять передвинем указатель p2 вперед на количество символов которое
содержалось в word1

p2 +=l_word1; // все слова теперь слева от указателя

Теперь указатель p2 указывает на первую чистую ячейку в массиве
word1.

3. Теперь подтянем указатель p1 массива buf на позицию, где находится
указатель p, а указатель p передвинем вперед на число символов
из которых состоит лексема word.

p1 = p;
p +=l_word;

}//end while 1

Теперь цикл while можно повторить чтобы искать следующее вхождение
лексемы word в строку, содержащуюся в массиве buf.

Цикл while повторится столько раз, сколько есть вхождений лексемы
в строку. После этого функция заголовка возвратит нуль и цикл
закончится Далее cкопируем в buf1 остаток строки из buf

strcpy(p2,p1);

Сохраним полученный результат, чтобы можно было использовать
(обработать) эту строку еще раз, но в поиске и замене уже другой лексемы
при новом вызове функции fun1 с новыми аргументами.

strcpy(p1a,p3);

То есть фактически копируем buf1 обратно в buf. При этом прежнее
содержимое buf стирается.

Примечание: Данная программа была написана мной для конкретной цели: При переводе книги Тома Негруна "JavaScript" в html-вариант, надо было сохранить формат строк оригинального издания. Где каждый тег такой как <IMG SRC= или <A HREF= начинается с новой строки. Следовательно надо было, чтобы программа отыскивала эти теги в строке и ставила впереди них тег <br>.


Назад | Начало урока | Вверх | Вперед
Содержание

Hosted by uCoz